package com.whfc.base.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import com.alibaba.fastjson.JSONArray;
import com.whfc.base.dao.*;
import com.whfc.base.dto.*;
import com.whfc.base.entity.AppRealtimeWeather;
import com.whfc.base.entity.AppSchedule;
import com.whfc.base.entity.AppWeatherTime;
import com.whfc.base.manager.WeatherMgr;
import com.whfc.base.service.WeatherService;
import com.whfc.common.enums.AppWeather;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ListData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.DateUtil;
import com.whfc.fuum.dto.AppProjectDTO;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

import static cn.hutool.core.date.DateUtil.beginOfDay;
import static com.whfc.common.enums.AppWeather.PARTLY_CLOUDY_DAY;

/**
 * 天气预报
 *
 * @author guodong_sun
 * @Description:
 * @date 2019年10月25日
 */
@DubboService(interfaceClass = WeatherService.class, version = "1.0.0")
public class WeatherServiceImpl implements WeatherService {

    private static final Logger logger = LoggerFactory.getLogger(WeatherService.class);

    /**
     * 天气预报刷新频率 单位h
     */
    private static final Integer REFRESH_WEATHER_FREQUENCY = 1;

    /**
     * 一周的天数
     */
    private static final Integer WEEK_DAYS = 6;

    @Autowired
    private WeatherMgr weatherMgr;

    @Autowired
    private AppWeatherMapper appWeatherMapper;

    @Autowired
    private AppWeatherTimeMapper appWeatherTimeMapper;

    @Autowired
    private AppRealtimeWeatherMapper appRealtimeWeatherMapper;

    @Autowired
    private AppHourlyWeatherMapper hourlyWeatherMapper;
    @Autowired
    private AppScheduleMapper scheduleMapper;


    @Override
    public WeatherDTO getWeather(Integer deptId, Double lng, Double lat) throws BizException {

        Date now = new Date();
        AppWeatherTime weatherTime = appWeatherTimeMapper.selectByDeptId(deptId);
        //需要更新预报天气
        if (weatherTime == null || weatherTime.getForecastWeatherTime() == null
                || now.getTime() - weatherTime.getForecastWeatherTime().getTime() >= REFRESH_WEATHER_FREQUENCY * 3600 * 1000) {
            //刷新预报天气
            try {
                weatherMgr.refreshWeather(deptId, lng, lat);
            } catch (Exception e) {
                throw new BizException(ResultEnum.FAILURE.getCode(),"天气刷新失败");
            }
        }

        //查询数据
        Date startTime = DateUtil.getDateBegin(now);
        Date endTime = DateUtil.addDays(startTime, WEEK_DAYS);
        List<AppWeatherDTO> list = appWeatherMapper.selectWeatherList(deptId, startTime, endTime);

        AppRealtimeWeather appRealtimeWeather = appRealtimeWeatherMapper.selectByDeptId(deptId);
        WeatherDTO data = new WeatherDTO();
        if (appRealtimeWeather != null) {
            data.setPrecipitationList(JSONArray.parseArray(appRealtimeWeather.getPrecipitation(), double.class));
            data.setTemperature(appRealtimeWeather.getTemperature());
            data.setWeather(appRealtimeWeather.getWeather());
            data.setWeatherPic(appRealtimeWeather.getWeatherPic());
            data.setDescription(appRealtimeWeather.getDescription());
            data.setWindSpeed(appRealtimeWeather.getWindSpeed());
        } else {
            data.setPrecipitationList(Collections.emptyList());
            data.setTemperature(0D);
            data.setWeather("");
            data.setWeatherPic("");
            data.setDescription("");
            data.setWindSpeed(0D);
        }
        data.setWeatherList(list);
        return data;
    }

    @Override
    public WeatherDTO realtimeWeather(Double lng, Double lat) throws BizException {
        AppRealtimeWeather appRealtimeWeather = weatherMgr.realtimeWeather(lng, lat);
        WeatherDTO data = new WeatherDTO();
        if (appRealtimeWeather != null) {
            data.setPrecipitationList(JSONArray.parseArray(appRealtimeWeather.getPrecipitation(), double.class));
            data.setTemperature(appRealtimeWeather.getTemperature());
            data.setWeather(appRealtimeWeather.getWeather());
            data.setTime(new Date());
            data.setWeatherPic(appRealtimeWeather.getWeatherPic());
            data.setDescription(appRealtimeWeather.getDescription());
            data.setWindSpeed(appRealtimeWeather.getWindSpeed());
        } else {
            data.setPrecipitationList(Collections.emptyList());
            data.setTemperature(0D);
            data.setTime(new Date());
            data.setWeather("");
            data.setWeatherPic("");
            data.setDescription("");
            data.setWindSpeed(0D);
        }
        return data;
    }

    @Override
    public ListData<AppWeatherLogDTO> getWeatherLog(Integer deptId, Date date) throws BizException {
        Date startTime = DateUtil.getDateBegin(date);
        Date endTime = DateUtil.getDateEnd(date);
        List<AppWeatherLogDTO> list = hourlyWeatherMapper.selectByDeptIdAndTime(deptId, startTime, endTime);
        for (AppWeatherLogDTO appWeatherLogDTO : list) {
            String weather = appWeatherLogDTO.getWeather();
            appWeatherLogDTO.setWeather(AppWeather.parseValue(weather).getDesc());
        }
        return new ListData<>(list);
    }

    @Override
    public ListData<AppWeatherLogDTO> getMonthWeatherHistory(Integer deptId, Date date) throws BizException {
        logger.info("获取历史天气预报(按月每天3个时间段),deptId:{},date:{}", deptId, date);
        String time = DateUtil.formatDate(date, DateUtil.MONTH_FORMAT);
        List<AppWeatherLogDTO> list = hourlyWeatherMapper.selectMonthByDeptIdAndTime(deptId, time);
        list.forEach(appWeatherLogDTO -> appWeatherLogDTO.setWeather(AppWeather.parseValue(appWeatherLogDTO.getWeather()).getDesc()));
        return new ListData<>(list);
    }

    @Override
    public AppWeatherDayDTO getDatWeather(Integer deptId, Date day) throws BizException {
        Date startTime = DateUtil.getDateBegin(day);
        Date endTime = DateUtil.getDateEnd(day);
        return hourlyWeatherMapper.selectDayByDateIdAndTime(deptId, startTime, endTime);
    }

    @Override
    public List<AppWeatherDTO> getWeekWeatherList(Integer deptId) throws BizException {
        logger.info("获取一周天气, deptId:{}", deptId);
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        calendar.add(Calendar.DAY_OF_MONTH, 7);
        Date endDate = calendar.getTime();
        return appWeatherMapper.selectWeatherList(deptId, now, endDate);
    }

    @Override
    public List<AppWeatherScheduleDTO> getMonthWeatherSchedule(Integer deptId, Date month,Integer userId,Double lng,Double lat) throws BizException {
        logger.info("获取本月天气, deptId:{}", deptId);
        List<AppWeatherScheduleDTO> ret = new ArrayList<>();
        DateTime dateTime = cn.hutool.core.date.DateUtil.beginOfMonth(month);
        DateTime dateTime1 = cn.hutool.core.date.DateUtil.endOfMonth(month);
        Date now = new Date();
        List<Date> dayListOfMonth = DateUtil.getDayListOfMonth(month);
        List<AppWeatherDTO> appWeatherDTOS = appWeatherMapper.selectWeatherList(deptId, dateTime, dateTime1);
        List<AppSchedule> appSchedules1 = new ArrayList<>();
        if(userId != null ){
            appSchedules1 = scheduleMapper.selectByUserIdAndBetweenTime(userId, dateTime, dateTime1);
        }
        Map<String,AppWeatherDTO> appWeatherDTOMap = new HashMap<>();
        Map<String,List<AppSchedule>> appSchedulesMap = new HashMap<>();
        appSchedules1.forEach(appSchedule -> {
            String selectTime = appSchedule.getSelectTime();
            String format = cn.hutool.core.date.DateUtil.format(cn.hutool.core.date.DateUtil.parse(selectTime), "yyyy-MM-dd");
            List<AppSchedule> orDefault = appSchedulesMap.getOrDefault(format, new ArrayList<AppSchedule>());
            orDefault.add(appSchedule);
            appSchedulesMap.put(format,orDefault);
        });
        appWeatherDTOS.forEach(appWeatherDTO -> {
            String s = cn.hutool.core.date.DateUtil.formatDate(appWeatherDTO.getDate());
            appWeatherDTOMap.put(s,appWeatherDTO);
        });

        dayListOfMonth.forEach(date -> {
            AppWeatherScheduleDTO appWeatherScheduleDTO = new AppWeatherScheduleDTO();
            String s = cn.hutool.core.date.DateUtil.formatDate(date);
            appWeatherScheduleDTO.setDate(date);
            appWeatherScheduleDTO.setAppWeatherDTO(appWeatherDTOMap.get(s));
            if(cn.hutool.core.date.DateUtil.between(beginOfDay(date),beginOfDay(now), DateUnit.DAY,false)<=0){
                //小于当前时间的不查日程
                List<AppSchedule> orDefault = appSchedulesMap.getOrDefault(s, new ArrayList<>());
                appWeatherScheduleDTO.setScheduleList(orDefault);
            }

            if(cn.hutool.core.date.DateUtil.between(beginOfDay(date),beginOfDay(now), DateUnit.DAY,false)==0){
                //当天
                WeatherDTO weatherDTO = realtimeWeather(lng, lat);
                String time = DateUtil.formatDate(now, DateUtil.DATE_FORMAT);
                List<AppWeatherLogDTO> list = hourlyWeatherMapper.selectMonthByDeptIdAndTheDay(deptId, time);
                list.stream().forEach(appWeatherLogDTO -> appWeatherLogDTO.setWeather(AppWeather.parseValue(appWeatherLogDTO.getWeather()).getDesc()));
                appWeatherScheduleDTO.setWeatherLogDTOList(list);
                AppWeatherDTO appWeatherDTO1 = new AppWeatherDTO();
                BeanUtils.copyProperties(weatherDTO ,appWeatherDTO1);
                appWeatherScheduleDTO.setAppWeatherDTO(appWeatherDTO1);
            }
            ret.add(appWeatherScheduleDTO);
        });




        return ret;
    }
}
